#include <stdio.h>

/*
 * 无符号非2的幂除数为负数反汇编代码还原
 */

int main(int argc, char* argv[])
{
	unsigned int NumberOne = 0;
	unsigned int NumberTwo = 0;

	scanf("%u",&NumberOne);
	scanf("%u",&NumberTwo);

	unsigned int Count1 = NumberOne / -3;

	unsigned int Count2 = NumberTwo / -5;

	unsigned int Count3 = NumberTwo / -6;

	unsigned int Count4 = NumberTwo / -9;

	printf("%d %d %d %d", Count4, Count3, Count2, Count1);

	return 0;
}

#if 0
	.text:00401005 mov [esp+8+var_8], eax
	.text:00401009 mov [esp+8+var_4], eax

	/-3
	.text:0040102B mov eax, 40000001h	// 1073741825
	.text:00401030 mov ecx, [esp+18h+var_4]
	.text:00401034 mul [esp+18h+var_8]
	.text:00401038 shr edx, 1Eh		// 2^(32+30) / 1073741825 = 4294967292.0000000037252902949925, 4294967292+1 = -3
	.text:00401040 push edx

	/-5
	.text:0040103B mov eax, 80000003h	// 2147483651
	.text:00401041 mul ecx
	.text:00401043 shr edx, 1Fh	// 2^(32+31) / 2147483651 = 4,294,967,290.0000000083819031598299, 4294967290+1 = -5
	.text:0040104B push edx

	/-6
	.text:00401046 mov eax, 7
	.text:0040104C mul ecx
	.text:0040104E mov eax, ecx
	.text:00401050 sub eax, edx
	.text:00401052 shr eax, 1
	.text:00401054 add eax, edx
	.text:00401056 shr eax, 1Fh
	.text:00401059 push eax
	
	/-9
	.text:0040105A mov eax, 80000005h	// 2147483653
	.text:0040105F mul ecx
	.text:00401061 shr edx, 1Fh		// 2^(32+31) / 2147483653 = 4,294,967,286.0000000232830643111769, 4294967286+1 = -9
	.text:00401064 push edx

/*
 * 代码定式
 */

	根据上面反汇编代码，看到三个地方有的疑似 (a * c) >> n的代码， 也就是除法转变为乘法的公式。

	随便取出一处代入公式进行还原：

	设 M = 40000001h =10进制的 1073741825

	设 n = 1E = 10进制的 30

	那么代入的还原公式为：	

		2^(32+30) / 1073741825 = 4294967292.0000000037252902949925

							   2^62 = 4,611,686,018,427,387,904 (64bit) = 0x4000000000000000 = 0  (32bit)
			4294967292 * 1073741825 = 4,611,686,018,427,387,900	(64bit) = 0x3FFFFFFFFFFFFFFC = -4 (32bit)

	以计算器的科学计算计算出的数值是 4294967292   (10进制)。

	那么将这个数复制到以程序员计算的计算器中(复制到Dec 10进制输入)可以看到是一个负数。

	4294967292 = 0xfffffffc = 1111 1111 1111 1111 1111 1111 1111 1100 = -4

	此时直接对其NOT取反则可以得到原始的被除数，但是这个被除数常量是负数。

	NOT(-4) = 0011 = 3

	你也可以让此值做+1调整变为 4294967293 ，那么就得出了数直接就是 -3 ，可以很明确的知道我们的被除数是 -3 。 

/*
 * 特殊汇编
 */

	看到上面有一段代码，我们特别不理解为什么/-6汇编变了。

	现在可以看一下算的：

	2^64 / 4,294,967,302 = 0x100000006，最高位为符号位，代表这是个负数也就是-6。

	如果根据定式还原得出的结果为0xFFFFFFF9，然后对其取反得到6。

	但是也有代码定式：

		mov regA,[ebp - xxx]
		mov reg,Mmul regA
		sub regA,edx
		shr regA,n
		add regA,edx
		shr regA,(n-1)

	观看代码定式可以得出："乘 减 移 加 移"。

	这种先使用定式还原：

        2^32 + n
        ---------
        2^32 + M

	这里取出两个n值。1+31= 32，所以n值为32。

	代入公式得：

	2^64 / 4,294,967,303 = 0XFFFFFFF9






#endif
